import { BaseUtil } from "../util/BaseUtil";
import { Constants } from "../data/Constants";
import { BaseValue } from "../data/BaseValue";

const { ccclass, property } = cc._decorator;


@ccclass
export class Fish extends cc.Component {

    @property({
        type: cc.SpriteAtlas
    })
    fishAtlas: cc.SpriteAtlas[] = [];

    @property({
        type: cc.Sprite
    })
    fish: cc.Sprite = null;

    private _halfWinWidth = Math.floor(cc.view.getVisibleSize().width) / 2;
    private _halfWinHeight = Math.floor(cc.view.getVisibleSize().height) / 2;
    private _currFrame = 1;
    private _type = 1;

    private _hp: number = 10;
    private _gold = 2;
    private _fishState;

    private _startPoint = [
        // 屏幕左侧
        { x: -this._halfWinWidth, y: BaseUtil.randomNum(-this._halfWinHeight, this._halfWinHeight) },

        // 屏幕右侧
        { x: this._halfWinWidth, y: BaseUtil.randomNum(-this._halfWinHeight, this._halfWinHeight) },

        // 屏幕上侧
        { x: BaseUtil.randomNum(-this._halfWinWidth, this._halfWinWidth), y: this._halfWinHeight },

        // 屏幕下侧
        { x: BaseUtil.randomNum(-this._halfWinWidth, this._halfWinWidth), y: -this._halfWinHeight },

    ];

    onLoad() {
        this.schedule(this._fishAnim, 0.1);
    }


    /**
     * 初始化鱼，设置精灵图、位置等
     * @param type 鱼类型
     */
    public setEntry(type: number) {
        let i = BaseUtil.randomNum(0, this._startPoint.length - 1);
        // 初始位置
        let offset = new cc.Vec2(this._startPoint[i].x, this._startPoint[i].y);
        // 设置初始精灵图
        this.fish.spriteFrame = this._getFishAtlasImage(type, 1);
        // 获取精灵图原始尺寸
        let rect = this.fish.spriteFrame.getRect().size
        // 设置鱼的类型，切换图片使用
        this._type = type;
        if (type > 10) {
            rect.width = rect.width / 3;
            rect.height = rect.height / 1.5;
        }
        this.node.setContentSize(rect);
        let collider = this.node.getComponent(cc.BoxCollider);
        collider.size = rect;

        if (i === 0) {
            //左侧
            offset.x -= rect.width;
            this.node.angle = 90;
        } else if (i === 1) {
            // 右侧
            offset.x += rect.width;
            this.node.angle = -90;
        } else if (i === 2) {
            // 上
            offset.y += rect.height;
            this.node.angle = 0;
        } else if (i === 3) {
            // 下
            offset.y -= rect.height;
            this.node.angle = -180;
        }
        if (type === 30) {
            this.node.angle = -180;
        }
        if (type === 29) {
            this.node.angle = 0;
        }

        this.node.setPosition(offset);

        this.node.name = BaseUtil.genSoleName('fish', type);
        this._hp = type * 10;
        this._gold = type * 10;
        this._fishState = Constants.FishStatus.ALIVE;

        this._fishMove(offset, Constants.MoveType.Line);
    }

    /**
     * 获取鱼图片帧
     * @param type 鱼种类
     * @param i 第几帧
     */
    private _getFishAtlasImage(type: number, i: number) {
        // fish_1: 1-21
        // fish_2: 22-26
        // fish_3: 27-30
        let result = this.fishAtlas[0].getSpriteFrame(`fish_1_1`);
        if (type > 26) {
            result = this.fishAtlas[2].getSpriteFrame(`fish_${type}_${i}`);
        } else if (type > 21) {
            result = this.fishAtlas[1].getSpriteFrame(`fish_${type}_${i}`);
        } else {
            result = this.fishAtlas[0].getSpriteFrame(`fish_${type}_${i}`);
        }
        return result;
    }

    private _fishMove(oriPos: cc.Vec2, moveType: number) {
        let time = BaseUtil.randomNum(5, 15);
        let end = this._genEndPosition(oriPos);

        switch (moveType) {
            case Constants.MoveType.Bezier:

                break;
            default:
                // this.node.angle += BaseUtil.getAngleByPos(oriPos, end);
                cc.tween(this.node)
                    .to(time, { position: end })
                    .call(() => {
                        BaseValue.FISH_POOL.put(this.node)
                    })
                    .start();
                break;
        }

    }


    private _genEndPosition(oriPos: cc.Vec2) {
        let end = cc.v2();
        if (oriPos.x > 0) {
            // 最右边
            end.x = BaseUtil.randomNum(-this._halfWinHeight, this._halfWinHeight);
            end.y = BaseUtil.randomNum(-this._halfWinHeight, this._halfWinHeight);

        } else if (oriPos.x <= 0) {
            // 最左边
            end.x = BaseUtil.randomNum(0, this._halfWinHeight);
            end.y = BaseUtil.randomNum(0, this._halfWinHeight);
        }

        return end;
    }


    private _fishAnim() {
        // 冰冻则不切换图片
        if (BaseValue.IS_FROZEN || this._fishState !== Constants.FishStatus.ALIVE) {
            return;
        }
        let frame = this._getFishAtlasImage(this._type, this._currFrame);
        this._currFrame++;
        if (BaseUtil.isEmpty(frame)) {
            frame = this._getFishAtlasImage(this._type, 1);
            this._currFrame = 1;
        }
        this.fish.spriteFrame = frame;
    }

    /**
     * 鱼和子弹碰撞后的处理
     * @param self 
     */
    public collisionBullet(self: cc.Collider, attackValue: number) {
        this.fish.node.color = cc.Color.GRAY;
        this._hp -= attackValue;
        if (this._hp <= 0 && this._fishState === Constants.FishStatus.ALIVE) {
            this._fishState = Constants.FishStatus.DEAD;
            this.node.stopAllActions();
            let collider = this.node.getComponent(cc.BoxCollider);
            let anim = this.fish.getComponent(cc.Animation);
            let clips = anim.getClips();
            let animName = clips[0].name;
            if (this._type > 18) {
                animName = clips[1].name;
            }
            cc.tween(this.node)
                .call(() => {
                    collider.enabled = false;
                    anim.play(animName);
                })
                .to(1, { scale: 0 })
                .call(() => {
                    this.node.scale = 1;
                    anim.stop(animName);
                    collider.enabled = true;
                    BaseValue.FISH_POOL.put(this.node)
                })
                .start();
            return this._gold;
        }
        return 0;
    }

    /**
     * 获取鱼的状态
     */
    public getFishStatus() {
        return this._fishState;
    }

}
